Configurar y utilizar puertos del microcontrolador como entrada o salida.
En el caso del Atmega168pa tenemos 3 registros de puertos distintos B, C y D referentes a los puertos:
NOTA: Por defecto el puerto PC6 no se puede utilizar, ya que se usa exclusivamente para RESET, para poder utilizar el puerto PC6 tenemos que deshabilitar RESET en los fuses del microcontrolador (RSTDISBL).
NOTA2: Si deshabilitamos el pin RESET no podremos volver a reprogramar el microcontrolador, CUIDADO CON ESTO !!!
Todos los registros que se ven a continuación son registros de 8 bits y funcionan como una máscara, de modo que por ejemplo 00000110 hace referencia al puerto 1 y 2.
Si leemos PORTB y vemos 00000001 quiere decir que el puerto 0 (si está configurado como output) tiene la salida activa
NOTA: En todos los proyectos siempre es aconsejable poner un condensador cerámico (de 100nF) entre VCC y GND para evitar picos en la alimentación del microcontrolador
Para configurar puertos lo hacemos con DDRB (Data Direction Register) en el caso del registro B.
Para los registros C y D sería DDRC y DDRD respectivamente
Por defecto todos los puertos están configurados como entrada (todos los bits a 0), si queremos poner el puerto 2 como salida por ejemplo lo haríamos con:
DDRB = 0b00000100
Una vez configurado un puerto como output para activar la salida (poner voltaje en alto en dicho puerto) lo hacemos con PORTB
Para los registros C y D sería PORTC y PORTD respectivamente
Para poner el puerto 2 y 3 del registro B como activos los haríamos con:
PORTB = 0b00001100
Al configurar un puerto como entrada podemos leer dicha entrada con PINB
Al leer dicho registro un 1 indica entrada activa y 0 entrada no activa
NOTA: El microcontrolador detecta como entrada activa todo voltaje mayor a VCC/2 y entrada no activa todo voltaje menor a VCC/2. (Por ejemplo si alimentamos el microcontrolador con 5V, todo valor superior a 2,5V será entrada activa y todo valor inferior a 2,5V será entrada no activa.)
Para los registros C y D sería PINC y PIND respectivamente
Si queremos consultar si el puerto 0 está con entrada activa:
if(PINB & 0b00000001)
Al configurar un puerto como entrada podemos usar PORTB (Para los registros C y D sería PORTC y PORTD respectivamente) para configurar pull-up resistor para cada uno de los puertos.
Para configurar el puerto 0 del registro B con pull-up resistor lo haríamos así:
PORTB = 0b00000001;
Hay que tener en cuenta que al configurar un pull-up resistor la entrada se invierte (de hecho la conexion fisica de un puerto con pull-up resistor configurado se hace a tierra y no a positivo) y al leer PINB un 0 indica entrada activa y 1 entrada no activa.
Si queremos consultar si el puerto 0 está con entrada activa:
if(!(PINB & 0b00000001))
En vez de usar la notación binaria podemos usar los macros referentes a los distintos puertos (PB0-7, PC0-6, PD0-7) y operaciones a nivel de bits para establecer los valores.
Por ejemplo para activar la salida en PB2 lo haríamos así:
PORTB = (1 << PB2);
Si queremos hacerlo manteniendo las demas salidas en su estado lo haríamos así:
PORTB |= (1 << PB2);
Si queremos desactivar la salida en PB2 manteniendo las demas salidas en su estado lo haríamos así:
PORTB &= ~(1 << PB2);
Si queremos configurar dos puertos como salida podemos hacerlo así:
DDRC = (1 << PC1) & (1 << PC3);
Tenemos dos funciones para comprobar si un bit está activo o no:
Para comprobar si el puerto 0 del registro B está con la entrada activada en vez de hacerlo así:
if(PINB & (1 << PB0))
Lo haríamos así:
if(bit_is_set(PINB, PB0))
Para comprobar si el puerto 0 del registro B está con la entrada desactivada en vez de hacerlo así:
if(!(PINB & (1 << PB0)))
Lo haríamos así:
if(bit_is_clear(PINB, PB0))
AVR | microcontrolador | IO